// TreeNews.ts
import {reactive, ref} from 'vue';
import {RowVO} from "../interface/VirtulTreeInterface";

// 虚拟树 扁平化的树形结构 list
export class TreeNews {
    private tree: RowVO[];
    private resultTrees: RowVO[];

    constructor() {
        this.tree = reactive<RowVO[]>([]);
        this.resultTrees = [] = reactive<RowVO[]>([]);
    }

    public getTree(): RowVO[] {
        return this.tree;
    }

    public getResultTrees(){
        return [...new Set(this.resultTrees)];
    }

    public getFirstNode(): RowVO | null {
        if(this.tree.length > 0){
            return this.tree[0];
        }else {
            return null;
        }
    }

    public clearTree(){
        this.tree = [];
    }

    public clearResultTree(){
        this.resultTrees = [];
    }

    public addNode(node: RowVO): void {
        this.tree.push(node);
    }

    public addNodes(nodes: RowVO[]):void{
        nodes.forEach((row) => {this.tree.push(row)})
    }

    // 更新 节点信息
    public updateNodeById(node: RowVO){
        const index = ref(0);
        while (index.value < this.tree.length){
            const currentNode = this.tree[index.value];
            if(currentNode.id === node.id){
                break;
            }
        }
        this.tree.splice(index.value, 1, node);
    }

    // 树形组件递归查找 目标节点
    private findNode(nodeId: string): RowVO | undefined {
        const queue: RowVO[] = [...this.tree];
        console.log('findNode queue:', queue)
        while (queue.length) {
            const node = queue.shift();
            console.log('findNode node:', node)
            if (node && node.id === nodeId) {
                return node;
            }
            if (node?.children) {
                queue.push(...node.children);
            }
        }
        return undefined;
    }

    // 根据ID查找目标节点
    private findNodeById(nodeId: string): RowVO|null{
        const queue: RowVO[] = [...this.tree];
        while (queue.length){
            const node = queue.shift();
            if(node && node.id === nodeId){
                // console.log('target:', node)
                return node;
            }
        }
        return null;
    }

    // 循环遍历，找到节点所有的父节点，添加到结果集中
    private addParentNode(nodeId: string|null){
        if(nodeId){
            const currentNode = this.findNodeById(nodeId);
            console.log('addParentNode:', nodeId, 'res:', currentNode)
            if(currentNode){
                currentNode.children = [];
                this.resultTrees.push(currentNode);
                if(currentNode.parentId){
                    this.addParentNode(currentNode.parentId);
                }
            }else {
                return false;
            }
        }else {
            return true
        }
    }

    // 编辑场景时，插入依赖表 的选定操作。 将勾选的字段，组装查询入参，调用接口 /dbutil/column 查询表信息
    public filterTableParams(nodes: RowVO[]) {
        const result = ref([]);
        nodes.forEach( (unit: RowVO) => {
            console.log("unit:", unit)
            if(unit.type === 'db_table'){
                const tableParams = reactive({id: '', db_id: '', database: '', table: '', columns: []});
                // @ts-ignore
                tableParams.id = unit.id;
                // @ts-ignore
                tableParams.db_id = unit.dbLink;
                // @ts-ignore
                tableParams.database = unit.dbBase;
                // @ts-ignore
                tableParams.table = unit.dbTable;
                tableParams.columns = [];
                nodes.forEach((row: RowVO) => {
                    if(row.type === 'db_field' && row.parentId === unit.id){
                        // @ts-ignore
                        tableParams.columns.push(row.name)
                    }
                })
                // @ts-ignore
                result.value.push(tableParams)
            }
        })
        return result.value;
    }

    // 条件筛选
    public filterTree(root: RowVO, condition: (node: RowVO) => boolean): RowVO | null {
        if (condition(root)) {
            // 找到后将其添加到结果列表中，并查找父节点同步添加进去
            this.resultTrees.push(root);
            this.addParentNode(root.parentId);
            return root;
        }
        if (root.children) {
           const filteredChildren: RowVO[] = [];
           for (const child of root.children) {
               const filteredChild = this.filterTree(child, condition);
               if (filteredChild) {
                   filteredChildren.push(filteredChild);
               }
           }
           if (filteredChildren.length > 0) {
               return { ...root, children: filteredChildren };
           }
        }
        return null;
    }
}
